/* intArmLib.h - ARM-specific interrupt library header file */

/* Copyright 1997-2003 Wind River Systems, Inc. */

/*
modification history
--------------------
01c,22aug03,to   added inline intLock()/intUnlock().
01b,20aug98,cdp  added intIFLock(), intIFUnlock().
01a,25nov97,cdp  created.
*/

#ifndef __INCintArmLibh
#define __INCintArmLibh

#ifdef __cplusplus
extern "C" {
#endif

/* interrupt model feature selection bits (OR'd together) */

#define INT_NON_PREEMPT_MODEL 0
#define INT_PREEMPT_MODEL 1
#define INT_HDWE_LOCK_LVL 2


/* inline intLock()/intUnlock() */

#if	!(ARM_THUMB)
#if	defined (__DCC__)
#define	_WRS_HAS_IL_INT_LOCK

__asm volatile int __inlineIntLock ()
{
! "r1"
	mrs		r1,cpsr
	and		r0,r1,#I_BIT
	orr		r1,r1,#I_BIT
	msr		cpsr,r1
}

__asm volatile void __inlineIntUnlock (int key)
{
% reg key;
! "r0", "r1"
	mrs		r1,cpsr
	bic		r1,r1,#I_BIT
	and		r0,key,#I_BIT
	orr		r1,r1,r0
	msr		cpsr,r1
}

#elif	defined (__GNUC__)
#define	_WRS_HAS_IL_INT_LOCK

/*
 * magic numbers used in inline asm:
 * #define I_BIT (1<<7) (from h/arch/arm/arm.h)
 */

static __inline__ int __inlineIntLock (void)
    {
    int key;
    __asm__ volatile (
	"mrs	r1, cpsr\n\t"
	"and	%0, r1, #(1<<7)\n\t"
	"orr	r1, r1, #(1<<7)\n\t"
	"msr	cpsr, r1"
	: "=g" (key)
	: /* no input */
	: "r1");
    return key;
    }

static __inline__ void __inlineIntUnlock (int key)
    {
    __asm__ volatile (
	"mrs	r1, cpsr\n\t"
	"bic	r1, r1, #(1<<7)\n\t"
	"and	r0, %0, #(1<<7)\n\t"
	"orr	r1, r1, r0\n\t"
	"msr	cpsr, r1"
	: /* no output */
	: "g" (key)
	: "r0", "r1");
    }
#else
#undef	_WRS_HAS_IL_INT_LOCK
#endif	/* __DCC__ */
#else
#undef	_WRS_HAS_IL_INT_LOCK
#endif	/* !ARM_THUMB */


/* functions in intArchLib.c */

extern STATUS intDisable (int);
extern STATUS intEnable (int);
extern STATUS intLibInit (int, int, int);
extern int    intIFLock (void);
extern void   intIFUnlock (int);


/* function pointers used in intArchLib.c and interrupt driver */
 
IMPORT FUNCPTR sysIntLvlVecChkRtn;
IMPORT FUNCPTR sysIntLvlVecAckRtn;
IMPORT FUNCPTR sysIntLvlChgRtn;
IMPORT FUNCPTR sysIntLvlEnableRtn;
IMPORT FUNCPTR sysIntLvlDisableRtn;

#ifdef __cplusplus
}
#endif

#endif /* __INCintArmLibh */
